今天主要介紹 IoT 嵌入式系統從開機到執行程式的完整流程與各階段的互動方式。
從按下電源鍵到載入 Bootloader、Firmware、Memory 的流程,大致可以 BIOS 和 UEFI 規格來說明:由左至右,第一階段的 Bootloader 原先以「初始化剛好足夠的硬體」出發,但隨著時間推移,已能支援執行時設定、GUI、Secure Boot、自動更新等功能。[1]


作為硬體與軟體之間的介接,Firmware 主要分成以下幾類型:
Embedded Firmware
│
┌──────────────────┼──────────────────┐
│ │ │
Bare Metal RTOS General-purpose OS
│ │ │
無 OS FreeRTOS Embedded Linux
Zephyr Android
ThreadX ...
VxWorks
QNX
RTEMS
...
Task → Callback → Parser → Memory operation → Peripheral
IoT 裝置的記憶體大致可分成以下幾類:
Volatile Memory(揮發性)
Non-Volatile Memory(非揮發性)
特殊用途
這些硬體儲存會被 Linux 透過 MTD(Memory Technology Device) 或 Block Device 抽象成 partition,再掛載成 SquashFS、JFFS2、UBIFS 等檔案系統。
以常見的 Embedded Linux Firmware 為例,內部大致包含:
Firmware
├── Bootloader ← 硬體初始化
├── Kernel / RTOS ← 作業系統核心
├── Root Filesystem (RootFS)
│ ├── BusyBox
│ ├── /lib
│ ├── /www
│ ├── /usr
│ ├── Vendor Applications
│ ├── Configuration Files
│ └── Startup Scripts
├── Data Partition ← 可讀寫資料(常為 JFFS2 / UBIFS)
├── NVRAM / MTD ← 非揮發性設定與校準資料
└── Firmware Update Mechanism

上圖引用 Zephyr RTOS 的架構 [2],用來對照 RTOS 的垂直分層。後文提到的 Driver、Kernel、Application 等概念在 RTOS 中的位置,可作為很好的參考。
用途:韌體啟動的第一段程式,負責硬體初始化與載入 Kernel,常見為 U-Boot 或廠商自製。
利用:在 Bootloader 階段可以提取 Kernel 與 RootFS,也是解密 firmware image 的常見切入點。

研究價值:
攻擊向量:
Bootloader Interaction
│
├── Console
│ └── UART / USB Serial
├── Network
│ └── TFTP / DHCP / HTTP / Recovery
├── Physical
│ └── Button / GPIO / USB / Storage
├── Debug
│ └── JTAG / SWD / DAP
├── Firmware Access
│ └── RAM / Flash / Boot Arguments
└── Security Boundary
├── Secure Boot
├── Signature Verification
├── Recovery
├── Downgrade
└── Fault Injection
以功能區分有以上這些類別,通常會使用對應工具進行探測,取得 interactive shell 與開機流程 Log。具體應用範例會在後續章節說明。
用途:作業系統核心,負責記憶體管理、行程排程、驅動載入等。可能是 Linux Kernel、RTOS(FreeRTOS、VxWorks 等)或完全客製。
互動:
int fd = open("/dev/wl0", O_RDWR); // 打開 WiFi 裝置
ioctl(fd, WL_IOCTL_SET_SSID, &ssid_struct); // 設定 SSID
ioctl(fd, WL_IOCTL_GET_SSID, &ssid_struct); // 讀取 SSID
close(fd);
用途:包含用戶空間的所有程式與設定檔(BusyBox、網路服務、設定檔、應用程式與 libraries)
互動:定位相關程式與設定檔位置,由於通常會使用不同的壓縮方式進行壓縮,解壓縮也不能單靠 binwalk,可以使用對應工具重建檔案架構和 linking
人類的話可以搭配 fzf 快速定位檔案,Agent 的部分之前試過 codegraph 種完 AST 之後再來逆向
hsqs
unsquashfs、dd、sasquatch
0x1985
jefferson
.ubi格式ubireader
0x28CD3D45
cramfsprog、firmware-mod-kit(有時候會有奇效)vmlinux2elf、yaffs2utils
以 RootFS 為例:
/
├── bin/ # busybox symlinks
├── sbin/
├── etc/ # init process, configs
│ ├── init.d/
│ ├── config/
│ ├── passwd
│ └── shadow
├── lib/
│ └── modules/
├── usr/
├── www/ # Web interface
│ ├── cgi-bin/
│ ├── luci/
│ └── htdocs/
├── dev/
├── proc/
├── sys/
└── tmp/
可以優先看看
/etc/init.d/:哪些服務會自動啟動?有無不安全參數?是否有隱藏 debug service?/www/:常見 Web Server 像是 lighttpd、CGI、uhttpd 等/etc/passwd & /etc/shadow:偶爾有奇怪的 MD5 hash 可用暴力破解RootFS、SquashFS 通常是唯讀,可寫入的資料會放在 Data Partition,常見掛載點為 /jffs、/overlay、/data,可用 mount 來查看
除了檔案系統,韌體還有一類的儲存,用來放設定值和校準資料
用途:儲存 WiFi 密碼、Admin 憑證、WAN/LAN 設定、Bootloader 參數等。
e.g.,
$ cat /proc/mtd
dev: size erasesize name
mtd0: 00040000 00010000 "u-boot"
mtd1: 00010000 00010000 "u-boot-env"
mtd2: 002b0000 00010000 "kernel"
mtd3: 00500000 00010000 "rootfs"
mtd4: 00010000 00010000 "nvram"
mtd5: 00010000 00010000 "art"
這邊也可以用dd dump出來看
了解韌體各層面的介紹後,我們可以對應回常見的攻擊手法:
| 層級 | 常見攻擊手法 |
|---|---|
| Bootloader | Secure Boot 繞過、改 bootargs |
| Kernel | LPE、vuln driver、已知 CVE |
| RootFS / App | Command Injection、BOF、Auth bypass |
| NVRAM | 憑證竊取、設定竄改 |
| Data / Overlay | Persistence、任意檔案寫入 |
| Update Mechanism | 未驗證韌體上傳 |
延伸閱讀:後續在討論 AI 輔助韌體研究時,會提到如何讓模型理解這類多層相依關係,以及一些專案中的實作結構。
你看了什麼:
你可以給 AI 什麼 insight:
畫個餅,之後有空會再讓AI把這些東西合併成一些 skills 來用,成功的話明天一起更新
明天我們會來看看如何從各種神奇地方取得 Firmware,以及如何選擇研究目標。
[1] https://medium.com/@tunacici7/bootloaders-the-wilderness-of-the-firmware-5a9b13c1bffd
[2] https://buildfromzero.com/posts/zephyr-rtos-taking-your-embedded-projects-to-the-next-level/
[3] https://dillan.org/articles/how-to-get-root-access-to-your-sleep-number-bed